<template>
  <div class="main-content">
    <div
      class="question"
      ref="questionContentRef"
      v-if="commentStore.currentQuestion.question_id"
    >
      <drawing-board
        :current-mode="props.currentMode"
        ref="questionDrawingBoard"
        @mouse-down="touchStart"
        @touch-start="touchStart"
        ><template #content>
          <div id="question-content-wrapper">
            <div
              v-if="
                !commentStore.similar.isShow &&
                questionData.typeDetail === 1 &&
                questionData.data.subproblem?.length === 0
              "
              class="single-choice"
            >
              <div
                :style="{ zoom: `${props.scale}` }"
                v-html="getParseRes.content"
              ></div>
              <ul :style="{ zoom: `${props.scale}` }">
                <li
                  class="choice-item"
                  v-for="(item, index) in getParseRes.options"
                  :key="index"
                >
                  <span class="tip">{{ getNum(letters[index]) }}人</span>
                  <span>{{ letters[index] }}.&ensp;</span>
                  <span v-html="item"></span>
                </li>
              </ul>
            </div>
            <RbQuestion
              v-else
              :style="{ zoom: `${props.scale}` }"
              :questionData="questionData"
              :option="rbqOption"
            >
            </RbQuestion>
          </div>
          <!-- 单选题 & 不是相似题 -->
        </template></drawing-board
      >
    </div>
    <a-divider v-if="answerVisible" class="divide" type="vertical"></a-divider>
    <div class="answer" ref="answerContentRef" v-show="answerVisible">
      <drawing-board
        :current-mode="props.currentMode"
        ref="answerDrawingBoard"
        @mouse-down="answerTouchStart"
        @touch-start="answerTouchStart"
      >
        <template #content>
          <div class="item">
            <p class="item__title">【参考答案】</p>
            <!-- 单选题 / 多选题 -->
            <template
              v-if="
                (questionData.data.type === 1 ||
                  questionData.data.type === 2) &&
                questionData.data.subproblem?.length === 0
              "
            >
              <template v-if="changedAnswer">
                <div class="item__content">
                  {{ changedAnswer }}
                  <p class="origin-answer">（原答案： {{ getAnswer }}）</p>
                </div>
              </template>
              <p class="item__content" v-else v-html="getAnswer || '略'"></p>
            </template>
            <!-- 判断题 -->
            <template v-else-if="questionData.data.type === 36">
              <template v-if="changedAnswer">
                <div class="item__content">
                  {{ changedAnswer }}
                  <p class="origin-answer">
                    （原答案：
                    {{ Number(getParseRes.answer) === 0 ? '正确' : '错误' }}）
                  </p>
                </div>
              </template>
              <p v-else class="item__content">
                {{ Number(getParseRes.answer) === 0 ? '正确' : '错误' }}
              </p>
            </template>
            <!-- 连线题 -->
            <template v-else-if="questionData.data.type === 49">
              <p
                v-for="(item, index) in questionDetail.accessory"
                :key="index"
                class="matching-question"
              >
                <span
                  class="matching-question__answer"
                  v-html="item.options.join('———')"
                ></span>
              </p>
            </template>
            <!-- 排序题 -->
            <template v-else-if="questionData.data.type === 69">
              <p class="item__content" v-if="isDigit(getParseRes.answer)">
                {{ getSortQuestionAnswer() }}
              </p>
              <p
                v-else
                class="item__content"
                v-html="getParseRes.answer || '略'"
              ></p>
            </template>
            <!-- 大题答案 -->
            <template
              v-else-if="
                getParseRes.subQuestions && getParseRes.subQuestions.length > 0
              "
            >
              <p
                class="item__content"
                v-for="(item, index) in getParseRes.subQuestions"
                :key="index"
              >
                ({{ index + 1 }})
                <template
                  v-if="
                    questionData.data.subproblem.length &&
                    (questionData.data.subproblem[index].type === 1 ||
                      questionData.data.subproblem[index].type === 2)
                  "
                >
                  {{
                    questionData.data.subproblem[index].correct_answer.join('')
                  }}
                </template>
                <template v-else>
                  <p v-html="item.answer || '略'"></p>
                </template>
              </p>
            </template>
            <template v-else>
              <p class="item__content" v-html="getParseRes.answer || '略'"></p>
            </template>
          </div>
          <div class="item">
            <p class="item__title">【解析】</p>
            <!-- 大题答案 -->
            <template
              v-if="
                getParseRes.subQuestions &&
                getParseRes.subQuestions.length > 0 &&
                getParseRes.subQuestions.some(item => item.solution)
              "
            >
              <div
                class="item__content"
                v-for="(item, index) in getParseRes.subQuestions"
                :key="index"
              >
                ({{ index + 1 }})
                <p v-html="item.solution"></p>
              </div>
            </template>
            <p
              v-else
              class="item__content"
              v-html="getParseRes.solution || '略'"
            ></p>
          </div>
          <div class="item">
            <p class="item__title">【知识点】</p>
            <div class="item__content key-point-list">
              <p
                v-for="(item, index) in questionDetail.keypoint"
                :key="index"
                class="key-point"
              >
                {{ item.name }}
              </p>
            </div>
          </div>
        </template>
      </drawing-board>
    </div>
    <similar-question
      :visible="similarVisible"
      @close-dialog="closeSimilarDialog"
    ></similar-question>
    <operate-tools
      @change-answer="changeAnswer"
      @change-response="changeResponseVisible"
      @half-screen="halfScreen"
      @show-similar="showSimilar"
      ref="operateToolsRef"
    />
    <response-detail
      :outer-half="outerHalf"
      :right-answer="changedAnswer ? changedAnswer : getAnswer"
      :visible="responseVisible"
      @close-dialog="closeResponseDialog"
      ref="responseDetailRef"
    />
    <ImagePreview
      v-if="previewSrc"
      :imgSrc="previewSrc"
      @close="previewSrc = ''"
    ></ImagePreview>
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted, onBeforeUnmount, nextTick } from 'vue'
import ImagePreview from './ImagePreview.vue'
import OperateTools from './OperateTools.vue'
import RbQuestion from '@ebag/rb-question-vue3'
import QuestionParser from '@ebag/rb-question-parser'
import ResponseDetail from './ResponseDetail.vue'
import SimilarQuestion from './SimilarQuestion.vue'
import DrawingBoard from './DrawingBoard.vue'
import { useAuthStore } from '@/stores/auth-store'
import { useComment } from '@/stores/comment'
import { useRoute } from 'vue-router'
import { getResponseStatistics } from '@/apis/assignment'
import { letters } from '../constant'
import { formatNum } from '@/utils/common'
import { WebSketch } from '@ebag/web-sketch'
const { userInfo } = useAuthStore()
const route = useRoute()
const webSketch = ref(null)
const answerWebSketch = ref(null)
const questionDrawingBoard = ref()
const answerDrawingBoard = ref()
const questionContentRef = ref()
const answerContentRef = ref()
const emits = defineEmits(['half-screen'])
const answerVisible = ref(false)
const responseVisible = ref(false)
const commentStore = useComment()
const questionEraserRef = ref()
const answerEraserRef = ref()
// 当前题目的详细信息
const questionDetail = computed(() => {
  return commentStore.similar.isShow
    ? commentStore.similar.selectedList[props.currentSimilar]
    : commentStore.currentQuestion.question_detail
})
// 撤销栈
const undoStack = ref([])
// 恢复栈
const redoStack = ref([])
const props = defineProps({
  scale: {
    default: 1,
    type: Number
  },
  currentSimilar: {
    default: 0,
    type: Number
  },
  currentMode: {
    type: String,
    default: 'select'
  }
})
const similarVisible = ref(false)
const optionList = ref(null)
const operateToolsRef = ref(null)
const responseDetailRef = ref(null)
const outerHalf = ref(false)
const questionCanvasRef = ref()
const answerCanvasRef = ref()
const rbqOption = ref({
  host: {
    resourceHost: 'https://contres.readboy.com/' // 静态资源(图片、音频等)服务器域名
  },
  displayAnswer: false, // 是否显示题目答案，显示答案时不能作答
  interactive: false, // 是否可作答
  readonly: true, // 可作答时是否只读（只显示之前的作答情况但不能改）
  // answerColor?: string; // 答案颜色，值为css颜色声明
  // enableContentFold?: boolean; // 是否启用题干折叠，默认不启用
  enableSolution: false, // 是否显示答案和解析，默认不显示
  fontSize: '0.1875rem',
  scaleImg: true
})

const questionData = computed(() => {
  const detail = commentStore.similar.isShow
    ? commentStore.similar.selectedList[props.currentSimilar]
    : commentStore.currentQuestion.question_detail
  const res = {
    typeDetail: detail.type || detail.category,
    data: detail
  }
  return res
})

const getParseRes = computed(() => {
  const res = QuestionParser.parse(questionData.value, rbqOption.value)
  return res
})

watch(
  () => questionData.value,
  async () => {
    if (webSketch.value && answerWebSketch.value) {
      revert('delete')
      draw(props.currentMode)
    }
    if (commentStore.currentQuestion.question_detail.type === 1) getDetail()
  },
  {
    deep: true
  }
)

const isDigit = str => {
  return /^\d+$/.test(str.join(''))
}

const getSortQuestionAnswer = () => {
  return getParseRes.value.answer.map(item => item + 1).join(',')
}

const getDetail = async () => {
  const params = {
    task_id: route.query.task_id,
    class_id: route.query.class_id,
    question_id: commentStore.currentQuestion.question_id,
    item_type: 1
  }
  const { data } = await getResponseStatistics(params)
  const result = data.result || {}
  const keys = Object.keys(result)
  // 单选
  if (data.statistics_type === 1) {
    optionList.value = keys.map(item => {
      return {
        key: item,
        total: result[item]?.list?.length || 0
      }
    })
  }
}

const getNum = desc => {
  if (optionList.value) {
    const item = optionList.value.find(item => item.key === desc)
    if (item) return item.total
  }
  return 0
}

// 原答案
const getAnswer = computed(() => {
  const answer = getParseRes.value.answer
  const res =
    getParseRes.value.structureType === 3
      ? answer
      : answer.map(item => letters[item])
  return res.join('')
})

// 修改后的答案
const changedAnswer = computed(() => {
  if (questionDetail.value.revised_answer) {
    const answer = questionDetail.value.revised_answer
    // 单选题/多选题
    if (
      questionData.value.typeDetail === 1 ||
      questionData.value.typeDetail === 2
    ) {
      const currentAnswer = answer || []
      const res = currentAnswer.map(item => letters[item])
      return answer.join('')
    } else if (questionData.value.data.type === 36) {
      // 判断题
      return Number(answer) === 0 ? '正确' : '错误'
    } else {
      return ''
    }
  } else {
    return ''
  }
})

const changeAnswer = val => {
  answerVisible.value = val
}

const changeResponseVisible = val => {
  responseVisible.value = val
}

const recoverFullScreen = () => {
  operateToolsRef.value.goHalfScreen()
}

const closeResponseDialog = () => {
  responseVisible.value = false
  if (operateToolsRef.value) {
    operateToolsRef.value.isShowDetail = false
  }
}

const halfScreen = val => {
  outerHalf.value = val
  emits('half-screen', val)
  if (
    responseVisible.value &&
    responseDetailRef.value &&
    responseDetailRef.value.isHalfScreen === !val
  ) {
    responseDetailRef.value.halfScreen()
  }
}

const showSimilar = () => {
  similarVisible.value = true
  changeResponseVisible(false)
  if (operateToolsRef.value) {
    operateToolsRef.value.isShowDetail = false
  }
}
const closeSimilarDialog = () => {
  similarVisible.value = false
  if (operateToolsRef.value) {
    operateToolsRef.value.isShowSimilar = false
  }
}

const createQuestionCanvas = () => {
  if (questionCanvasRef.value) {
    questionCanvasRef.value.height = questionContentRef.value.offsetHeight * 3
    questionCanvasRef.value.width = innerWidth
    webSketch.value = new WebSketch(questionCanvasRef.value)
  }
}

const draw = type => {
  questionDrawingBoard.value && questionDrawingBoard.value.draw(type)
  answerDrawingBoard.value && answerDrawingBoard.value.draw(type)
}

const revert = type => {
  // 删除
  if (type === 'delete') {
    questionDrawingBoard.value && questionDrawingBoard.value.revert(type)
    answerDrawingBoard.value && answerDrawingBoard.value.revert(type)
    undoStack.value = []
    redoStack.value = []
  } else if (type === 'recover') {
    // 恢复
    if (redoStack.value.length <= 0) return
    const current = redoStack.value.at(-1)
    if (current === 'question') {
      questionDrawingBoard.value && questionDrawingBoard.value.revert(type)
    } else {
      answerDrawingBoard.value && answerDrawingBoard.value.revert(type)
    }
    undoStack.value.push(redoStack.value.pop())
  } else {
    // 撤销
    if (undoStack.value.length <= 0) return
    const current = undoStack.value.at(-1)
    if (current === 'question') {
      questionDrawingBoard.value && questionDrawingBoard.value.revert(type)
    } else {
      answerDrawingBoard.value && answerDrawingBoard.value.revert(type)
    }
    redoStack.value.push(undoStack.value.pop())
  }
}

const touchStart = () => {
  undoStack.value.push('question')
}

const answerTouchStart = () => {
  undoStack.value.push('answer')
}

watch(
  () => answerVisible.value,
  val => {
    nextTick(() => {
      questionDrawingBoard.value &&
        questionDrawingBoard.value.changeCanvasHeight(true)
      if (val)
        answerDrawingBoard.value &&
          answerDrawingBoard.value.changeCanvasHeight()
    })
  }
)

watch(
  () => props.scale,
  () => {
    nextTick(() => {
      questionDrawingBoard.value &&
        questionDrawingBoard.value.changeCanvasHeight(true)
    })
  }
)

watch(
  () => commentStore.currentQuestion.question_id,
  () => {
    nextTick(() => {
      previewSrc.value = ''
      revert('delete')
      questionDrawingBoard.value &&
        questionDrawingBoard.value.changeCanvasHeight()
      answerDrawingBoard.value && answerDrawingBoard.value.changeCanvasHeight()
    })
  }
)

// 查看题目图片对应大图
const previewSrc = ref()
const handleClick = e => {
  e.stopPropagation()
  if (e.target.tagName === 'IMG') {
    previewSrc.value = e.target.src
  }
}

onMounted(() => {
  setTimeout(() => {
    const box = document.getElementById('question-content-wrapper')
    if (box) {
      box.addEventListener('click', e => {
        if (e.target.tagName === 'IMG') {
          handleClick(e)
        }
      })
    }
  }, 500)
})

onBeforeUnmount(() => {
  const box = document.getElementById('question-content-wrapper')
  box?.removeEventListener('click', handleClick)
})

defineExpose({
  recoverFullScreen,
  draw,
  revert
})
</script>
<style lang="less" scoped>
.main-content {
  position: relative;
  padding: 0 32px 116px 32px;
  box-sizing: border-box;
  height: 100%;
  width: 100%;
  display: flex;
  overflow-x: hidden;

  * {
    user-select: none;
  }

  .question,
  .answer {
    * {
      color: rgba(255, 255, 255, 0.9);
    }
  }

  .canvas {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 1;
  }

  .question {
    position: relative;
    padding-right: 20px;
    flex: 1;
    overflow-y: auto;
    overflow-x: hidden;
    &::-webkit-scrollbar {
      width: 0px !important;
    }

    .single-choice {
      padding-top: 32px;

      :deep(*) {
        img {
          background: #fff !important;
        }
      }
      .choice-item {
        display: flex;
        align-items: self-start;
        margin-bottom: 20px;
      }
      .tip {
        min-width: fit-content;
        font-size: 16px;
        margin-top: 11px;
        border-radius: 4px;
        display: inline-block;
        border: 1px solid #fff;
        padding: 4px;
        margin-right: 10px;
      }
      :deep(*) {
        color: rgba(255, 255, 255, 0.9);
        font-size: 36px;
      }
    }

    :deep(.rb-question) {
      padding: 32px 0 0 0;
      * {
        color: rgba(255, 255, 255, 0.9);
      }

      .rbq-blk {
        font-family: auto;
      }

      img {
        background: #fff !important;
      }

      .xuan-ci-tian-kong {
        * {
          color: #fff;
        }
      }

      .slot-wrapper {
        margin: 0;
        padding-top: 10px;
        .rate {
          margin: 0 8px;
          border-radius: 4px;
          border: 1px solid rgba(76, 223, 192, 1);
          color: rgba(76, 223, 192, 1);
          font-size: 16px;
          padding: 4px;
        }
      }

      .content-container {
        background: inherit;
        padding: 0;
      }

      .option-list-choice {
        padding: 0;

        li {
          display: flex;
          align-items: flex-start;
        }
      }

      .rbq-content {
        overflow: hidden;
        p {
          margin-top: 0;
        }
      }
    }
  }

  .matching-question {
    padding-left: 18px;

    &__answer {
      display: flex;
    }
  }

  .divide {
    width: 1px;
    background: #fff;
    height: 100%;
    right: 0;
    top: 0;
    bottom: 0;
  }

  .answer {
    position: relative;
    flex: 1;
    font-size: 32px;
    overflow-y: auto;
    overflow-x: hidden;
    :deep(*) {
      img {
        background: #fff !important;
      }
    }
    &::-webkit-scrollbar {
      width: 0 !important;
    }

    .item {
      margin-bottom: 24px;
      :deep(*) {
        color: rgba(255, 255, 255, 0.9);
      }

      &__content {
        margin-top: 18px;
        padding-left: 29px;
        width: calc(100% - 20px);

        .origin-answer {
          color: rgba(255, 255, 255, 0.6);
        }
      }

      .key-point-list {
        display: flex;
        flex-direction: column;
        gap: 10px;

        .key-point {
          display: inline-block;
          border-radius: 8px;
          padding: 24px 16px;
          background: rgba(230, 248, 244, 0.8);
          color: rgba(0, 189, 141, 1);
          width: fit-content;
        }
      }
    }
  }
}
</style>
